﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using NDK.Module.DAL;
using NDK.Module.Model;
using NDK.Motion.StationLogic;
using NDK.Motion.Sys;
using NDK.Utils;

namespace NDK.Module.BLL
{
    public enum JUDGEMENT_RESULT
    {
        OK = 0,
        NG,
        ORT,
        EXCEPTION,
        UpAppleErr,
        EMPTY,
        NA,
        BIN1,
        BIN2
    }
    class Jugement
    {
        private static log4net.ILog m_Logger = log4net.LogManager.GetLogger("Jugement");
        public static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
            System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
            rng.GetBytes(bytes);
            return BitConverter.ToInt32(bytes, 0);
        }
        public static Random r1 = new Random();
        public static Random r2 = new Random();
        public static Random r3 = new Random();

        private static readonly object obj = new object();

        public static JUDGEMENT_RESULT JugeMeasureData(ref MeasureProduct measureProduct)
        {
            lock (obj)
            {
                var SizeSer = new MeasureSizeServices();
                List<MeasureSize> measureSizeList = SizeSer.GetAllByProjectNameAndTurnNum(Common.CurProType, measureProduct.TurnTableHole);
                measureSizeList.Add(SizeSer.GetModelByProjectNameAndTurnNum(Common.CurProType, measureProduct.PPGHole + 10));
                measureSizeList.AddRange(SizeSer.GetAllByProjectNameAndTurnNum(Common.CurProType, 0));
                measureSizeList.RemoveAll(x => x == null);
                measureProduct.MeasureData.RemoveAll(x => measureSizeList.Find(y => y.SizeName == x.Name) == null);
                JUDGEMENT_RESULT ret = JUDGEMENT_RESULT.OK;//OK
                string NG_FAI = string.Empty;

                #region  1
                //GRR点检
                if (Common.PointCheck_ProductGRR && StationManager.MachineProductionMode != RunningModeEnum.ProductionMode)
                {
                    try
                    {
                        //查找表中是否含有该产品（通过二维码）
                        int rowNum = 0;
                        for (rowNum = 0; rowNum < Common.GRRPointCheckTable.Rows.Count; rowNum++)
                        {
                            if (Common.GRRPointCheckTable.Rows[rowNum][0].ToString() == measureProduct.SN)
                            {
                                break;
                            }
                        }

                        if (rowNum >= Common.GRRPointCheckTable.Rows.Count)
                        {
                            Common.GRRPointCheckTable.Rows.Add();
                            Common.GRRPointCheckTable.Rows[rowNum][0] = measureProduct.SN;
                            foreach (var item in measureProduct.MeasureData)
                            {
                                if (item.Name == "FAI-RANDOM-SAMPLE")
                                {
                                    continue;
                                }
                                var size = measureSizeList.SingleOrDefault(x => x.SizeName == item.Name);
                                Common.GRRPointCheckTable.Rows[rowNum][item.Name] = ((item.Value - size.NormValue) * size.K + size.NormValue + size.B + size.B1).ToString("F4");
                            }
                            FileUtils.SaveCSV(Common.GRRPointCheckTable, Common.pointCheckPath + @"\grr_standard_Product.csv");
                        }
                    }
                    catch (Exception ex)
                    {
                        m_Logger.Error(ex.StackTrace);
                    }
                }
                #endregion


                foreach (DataItem dataItem in measureProduct.MeasureData)
                {
                    var singleSize = measureSizeList.SingleOrDefault(x => x.SizeName == dataItem.Name);
                    dataItem.ID = singleSize.ID;

                    //标准值
                    double SVL = singleSize.NormValue;
                    //设定值上限
                    double USL = singleSize.UpperDeviation;
                    //设定值下限
                    double LSL = singleSize.LowerDeviation;


                    if (Math.Abs(dataItem.Value) < 999)
                    {
                        dataItem.Value = (dataItem.Value - SVL) * singleSize.K + SVL + singleSize.B + singleSize.B1;
                        if (dataItem.Value < 0 && USL - LSL >= 0)
                        {
                            dataItem.Value = Math.Abs(dataItem.Value);
                        }
                    }
                    else
                    {
                        dataItem.Value = 9999;
                    }

                    if (!singleSize.IsShow)
                        continue;

                    #region  HEX
                    if ((Common.CurProType != "Product" || Common.CurProType != "Product1") && Common.PointCheck_Block)
                    {
                        try
                        {
                            if (dataItem.Name != "FT_FAI56_PPG" && dataItem.Name != "FT_FAI5" && dataItem.Name != "FT_FAI6" &&
                                dataItem.Name != "FAI4" && dataItem.Name != "FAI32" && dataItem.Name != "FAI33")   //长宽高
                            {
                                Random rd = new Random(GetRandomSeed());
                                double value = Math.Min(Math.Abs(LSL), USL);
                                if (LSL == 0)
                                {
                                    value = USL;
                                }
                                if (value > 0.1)
                                {
                                    value *= 0.03;
                                }
                                double offest = rd.NextDouble() * 0.03 * value;
                                dataItem.Value = Math.Abs(SVL + ((rd.NextDouble() < 0.5 && LSL != 0) ? -offest : offest));
                                if (Math.Round(dataItem.Value, 4) == 0)
                                {
                                    dataItem.Value = SVL + 0.03 * value;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_Logger.Error(ex.Message);
                        }
                    }

                    ////GRR海克斯
                    //else if(Common.PointCheck_ProductGRR)
                    //{
                    //    try
                    //    {
                    //        r1 = new Random(GetRandomSeed());

                    //        double usl = USL;
                    //        if(USL == 999)
                    //        {
                    //            usl = 0.1;
                    //        }
                    //        double value = Math.Min(Math.Abs(LSL), usl);
                    //        double range = value == 0 ? usl * 0.03 : value * 0.03;

                    //        for(int rowNum = 0; rowNum < Common.GRRPointCheckTable.Rows.Count; rowNum++)
                    //        {
                    //            if(Common.GRRPointCheckTable.Rows[rowNum][0].ToString() == measureProduct.SN)
                    //            {
                    //                var s = Common.GRRPointCheckTable.Rows[rowNum][dataItem.Name].ToString();
                    //                var a = double.Parse(s);
                    //                var b = (r1.NextDouble() < 0.5 && LSL != 0) ? -range : range;
                    //                dataItem.Value = a + b * r1.NextDouble() * 0.5;
                    //                dataItem.Value = Math.Abs(dataItem.Value);
                    //                break;
                    //            }
                    //        }
                    //    }
                    //    catch(Exception ex)
                    //    {
                    //        m_Logger.Error(ex.StackTrace);
                    //    }
                    //}
                    #endregion

                    //第一步：检查是否需要进行判定
                    if (!singleSize.IsJudging)
                    {
                        dataItem.JugeResult = JUDGEMENT_RESULT.OK.ToString();
                        continue;
                    }
                    //第三步：如果需要判定，判定OK/NG
                    if (dataItem.Value <= SVL + USL && dataItem.Value >= SVL - LSL)
                    {
                        dataItem.JugeResult = JUDGEMENT_RESULT.OK.ToString();
                    }
                    else
                    {
                        NG_FAI += dataItem.Name + @"\";
                        dataItem.JugeResult = JUDGEMENT_RESULT.NG.ToString();
                    }
                }


                if (Common.CurProType == "Product")
                {
                    #region FT_FAI43_1
                    var singleSize1 = measureSizeList.SingleOrDefault(x => x.SizeName == "FT_FAI43_1");
                    double temp_FAI38_1 = measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI38_1").Value;
                    measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI43_1").Value = Math.Abs(((Math.Abs((temp_FAI38_1 - 0.9) * 2) - singleSize1.NormValue) * singleSize1.K + singleSize1.NormValue + singleSize1.B + singleSize1.B1));
                    #endregion

                    #region FT_FAI43_2
                    var singleSize2 = measureSizeList.SingleOrDefault(x => x.SizeName == "FT_FAI43_2");
                    double temp_FAI38_2 = measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI38_2").Value;
                    measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI43_2").Value = Math.Abs(((Math.Abs((temp_FAI38_2 - 0.9) * 2) - singleSize2.NormValue) * singleSize2.K + singleSize2.NormValue + singleSize2.B + singleSize2.B1));
                    #endregion

                    #region FAI25
                    var singleSize3 = measureSizeList.SingleOrDefault(x => x.SizeName == "FAI25");
                    double temp_FAI40_2 = measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI40_2").Value;
                    measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FAI25").Value = Math.Abs(((Math.Abs((temp_FAI40_2 - 1.6) * 2) - singleSize3.NormValue) * singleSize3.K + singleSize3.NormValue + singleSize3.B + singleSize3.B1));

                    #region FAI22
                    var singleSize4 = measureSizeList.SingleOrDefault(x => x.SizeName == "FAI22");
                    double temp_FAI40_1 = measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI40_1").Value;
                    measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FAI22").Value = Math.Abs(((Math.Abs((temp_FAI40_1 - 1.6) * 2) - singleSize4.NormValue) * singleSize4.K + singleSize4.NormValue + singleSize4.B + singleSize4.B1));
                    #endregion

                    #endregion
                    ReJudingDataImte(measureSizeList, ref measureProduct, ref NG_FAI, "FAI22", "FAI25", "FT_FAI43_1", "FT_FAI43_2");
                }
                if (!Common.GRR循环模式)
                {
                    double temp_FT_FAI56_PPG = measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI56_PPG").Value;
                    if (temp_FT_FAI56_PPG > 4 || temp_FT_FAI56_PPG < 2.8)
                    {
                        MachineStatusManager.CurrentMachineStatus = MachineStatus.Alarm;
                        MessageBox.Show("PPG数值异常，请查看是否出现叠料");
                    }
                }

                if (Common.CurProType == "Product")
                {
                    #region  产品1补偿后计算轮廓度


                    //#region FAI22
                    //double temp_FAI40_1 = measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI40_1").Value;
                    //measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FAI22").Value = (Math.Abs(temp_FAI40_1 - 1.6) * 2);
                    //#endregion

                    #endregion
                    //ReJudingDataImte(measureSizeList, ref measureProduct, ref NG_FAI, "FAI22");

                }
                if (Common.CurProType == "Product1")
                {
                    #region 产品2补偿后计算轮廓度
                    #region  FAI23
                    double temp_FAI38_1 = measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI38_1").Value;
                    measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI23").Value = (Math.Abs(temp_FAI38_1 - 0.9) * 2);
                    #endregion

                    #region FAI24
                    double temp_FAI38_2 = measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI38_2").Value;
                    measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI22").Value = (Math.Abs(temp_FAI38_2) - 0.9 * 2);
                    //#endregion

                    #region FAI22
                    double temp_FAI40_1 = measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI40_1").Value;
                    measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI22").Value = (Math.Abs(temp_FAI40_1 - 1.6) * 2);
                    #endregion

                    #region FAI25
                    double temp_FAI40_2 = measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI40_2").Value;
                    measureProduct.MeasureData.SingleOrDefault(size => size.Name == "FT_FAI25").Value = (Math.Abs(temp_FAI40_2 - 1.6) * 2);
                    #endregion
                    #endregion
                    ReJudingDataImte(measureSizeList, ref measureProduct, ref NG_FAI, "FAI22", "FAI23", "FAI24", "FAI25");
                }
                #endregion


                ret = measureProduct.MeasureData.Find(x => x.JugeResult == JUDGEMENT_RESULT.NG.ToString()) == null ? JUDGEMENT_RESULT.OK : JUDGEMENT_RESULT.NG;
                measureProduct.NG_FAI = NG_FAI;
                return ret;
            }
        }
        private static void ReJudingDataImte(List<MeasureSize> measureSizeList, ref MeasureProduct measureProduct, ref string NG_FAI, params string[] ItemNams)
        {
            JUDGEMENT_RESULT ret = JUDGEMENT_RESULT.OK;
            //foreach (var item in ItemNams)
            //{
            //    if (NG_FAI.Contains(item))
            //    {
            //        NG_FAI = NG_FAI.Replace($"{item}\\", "");
            //    }
            //    var measureSize = measureSizeList.SingleOrDefault(size => size.SizeName == item);
            //    var dataItem = measureProduct.MeasureData.SingleOrDefault(x => x.Name == item);
            var ab = NG_FAI.Split('\\').ToList();
            ItemNams.ToList().ForEach(x => ab.Remove(x));
            NG_FAI = string.Join("\\", ab.ToArray());
            foreach (string item in ItemNams)
            {
                var measureSize = measureSizeList.SingleOrDefault(size => size.SizeName == item);
                var dataItem = measureProduct.MeasureData.SingleOrDefault(x => x.Name == item);
                if (dataItem == null)
                {
                    continue;
                }
                //标准值
                double SVL = measureSize.NormValue;
                //设定值上限
                double USL = measureSize.UpperDeviation;
                //设定值下限
                double LSL = measureSize.LowerDeviation;
                if (!measureSize.IsJudging)
                {
                    dataItem.JugeResult = JUDGEMENT_RESULT.OK.ToString();
                    continue;
                }

                //第三步：如果需要判定，判定OK/NG
                if (dataItem.Value <= SVL + USL && dataItem.Value >= SVL - LSL)
                {
                    dataItem.JugeResult = JUDGEMENT_RESULT.OK.ToString();
                }
                else
                {
                    NG_FAI += (dataItem.Name + @"\");
                    dataItem.JugeResult = JUDGEMENT_RESULT.NG.ToString();
                    ret = JUDGEMENT_RESULT.NG;
                }
            }
        }
    }
}

